import os
import os.path


class Package:
  def __init__(self, path):
    self.prefix = os.path.realpath(path)

  def exists(self, filename):
    p = os.path.realpath(self.prefix + '/' + filename)
    return os.path.exists(p)

  def filenames(self, prefix=None):
    if prefix:
      prefix = os.path.realpath(self.prefix + '/' + prefix)
    files = []
    for d, dd, df in os.walk(self.prefix):
      files.extend([os.path.realpath(d + '/' + f) for f in df])
    files.sort()
    return [file for file in files if not prefix or file.startswith(prefix)]

  def open(self, filename):
    return open(os.path.realpath(self.prefix + '/' + filename), 'rb')


files = []
packages = []

def add(package):
  required = ['exists', 'filenames', 'open']
  for method in required:
    if not hasattr(package, method):
      raise Exception, 'Package "%s" must implement method "%s"' % (package.__class__.__name__, method)
  packages.append(package)

def add_path(path):
  packages.append(Package(path))

def exists(filename):
  for package in packages:
    if package.exists(filename):
      return True
  return False

def filenames(prefix=None):
  names = []
  for package in packages:
    names.extend(package.filenames(prefix))
  names.sort()
  return names

def open(filename):
  for package in packages:
    if package.exists(filename):
      return package.open(filename)
  raise IOError, 'File not found'

def remove(package):
  try:
    del packages[packages.index(package)]
  except ValueError:
    pass
